package org.lyfeng.spring.aop;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import org.lyfeng.spring.beans.definitions.BeanDefinition;
import org.lyfeng.spring.exception.BeanNameDuplicateException;

/**
 * @author leiyufeng
 * 2013-4-26 下午4:57:34
 */
public abstract class AbstractAspectRegister implements AspectRegister{
	/**保存bean的切面处理：bean name--->class<?>   **/
	private Set<Class<?>> aspectSet=new LinkedHashSet<Class<?>>();
	protected Map<String,Class<?>> aspectMap=new ConcurrentHashMap<String,Class<?>>();
	
	protected final Map<String,BeanDefinition> aspectDefinitionsMap=new ConcurrentHashMap<String,BeanDefinition>();
	
	/**保存代理的对象   ：bean name--->proxy object **/
	protected final Map<String,Object> singleonProxyObjectsMap=new ConcurrentHashMap<String, Object>(64);
	
	/**aspect也是作为bean被spring容器管理的**/
	protected Map<String,Object> aspectBeanMap=new ConcurrentHashMap<String, Object>();
	@Override
	public synchronized void registerAspect(String beanName,Class<?> clazz) {
		aspectMap.put(beanName, clazz);
	}

	@Override
	public void registerBeanDefinition(BeanDefinition beanDefinition) {
		synchronized (aspectDefinitionsMap) {
			aspectDefinitionsMap.put(beanDefinition.getBeanName(), beanDefinition);
		}
	}

	@Override
	public synchronized void removeAspect(String beanName) {
		aspectMap.remove(beanName);
	}

	@Override
	public void registerAspect(Class<?> clazz) {
		aspectSet.add(clazz);
		//初始化aspectMap
		//待完善
	}

	@Override
	public void registerProxyObject(String beanName, Object proxyObject) {
		singleonProxyObjectsMap.put(beanName, proxyObject);
	}
	
	public Object getProxyObject(String beanName)
	{
		return singleonProxyObjectsMap.get(beanName);
	}

	@Override
	public void addAspectBean(String beanName, Object obj) {
		synchronized (aspectBeanMap) {
			if(aspectBeanMap.containsKey(beanName))
			{
				throw new BeanNameDuplicateException();
			}
			aspectBeanMap.put(beanName, obj);
		}
	}
	
	@SuppressWarnings("rawtypes")
	public List<Object> getAopBeanAsList()
	{
		Iterator it=aspectBeanMap.entrySet().iterator();
		List<Object> list=new ArrayList<Object>();
		while(it.hasNext())
		{
			Map.Entry entry=(Entry) it.next();
			list.add(entry.getValue());
		}
		return list;
	}
}
